From: Jan Beulich Date: Tue, 16 Aug 2011 14:05:30 +0000 (+0100) Subject: passthrough: don't use open coded IO-APIC accesses X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~9962 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22?a=commitdiff_plain;h=71abd26c352d6876f60050a2c624dc60e2ac01e3;p=xen.git passthrough: don't use open coded IO-APIC accesses This makes the respective functions quite a bit more legible. Since this requires fiddling with __ioapic_{read,write}_entry() anyway, make them and their wrappers have their argument types match those of __io_apic_{read,write}() (int -> unsigned int). No functional change intended. Signed-off-by: Jan Beulich --- diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c index 258f341c25..411e726b67 100644 --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c @@ -162,7 +162,8 @@ union entry_union { struct IO_APIC_route_entry entry; }; -static struct IO_APIC_route_entry __ioapic_read_entry(int apic, int pin, int raw) +struct IO_APIC_route_entry __ioapic_read_entry( + unsigned int apic, unsigned int pin, bool_t raw) { unsigned int (*read)(unsigned int, unsigned int) = raw ? __io_apic_read : io_apic_read; @@ -172,7 +173,8 @@ static struct IO_APIC_route_entry __ioapic_read_entry(int apic, int pin, int raw return eu.entry; } -static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin, int raw) +static struct IO_APIC_route_entry ioapic_read_entry( + unsigned int apic, unsigned int pin, bool_t raw) { struct IO_APIC_route_entry entry; unsigned long flags; @@ -183,8 +185,9 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin, int raw) return entry; } -static void -__ioapic_write_entry(int apic, int pin, int raw, struct IO_APIC_route_entry e) +void __ioapic_write_entry( + unsigned int apic, unsigned int pin, bool_t raw, + struct IO_APIC_route_entry e) { void (*write)(unsigned int, unsigned int, unsigned int) = raw ? __io_apic_write : io_apic_write; @@ -195,7 +198,9 @@ __ioapic_write_entry(int apic, int pin, int raw, struct IO_APIC_route_entry e) (*write)(apic, 0x10 + 2*pin, eu.w1); } -static void ioapic_write_entry(int apic, int pin, int raw, struct IO_APIC_route_entry e) +static void ioapic_write_entry( + unsigned int apic, unsigned int pin, bool_t raw, + struct IO_APIC_route_entry e) { unsigned long flags; spin_lock_irqsave(&ioapic_lock, flags); diff --git a/xen/drivers/passthrough/amd/iommu_intr.c b/xen/drivers/passthrough/amd/iommu_intr.c index f67bfb6d1c..4e6efa096f 100644 --- a/xen/drivers/passthrough/amd/iommu_intr.c +++ b/xen/drivers/passthrough/amd/iommu_intr.c @@ -374,13 +374,6 @@ void amd_iommu_msi_msg_update_ire( update_intremap_entry_from_msi_msg(iommu, pdev, msi_desc, msg); } -unsigned int amd_iommu_read_ioapic_from_ire( - unsigned int apic, unsigned int reg) -{ - *IO_APIC_BASE(apic) = reg; - return *(IO_APIC_BASE(apic)+4); -} - void amd_iommu_read_msi_from_ire( struct msi_desc *msi_desc, struct msi_msg *msg) { diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/passthrough/amd/pci_amd_iommu.c index d295f7f158..6af9477076 100644 --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c @@ -467,6 +467,8 @@ static int amd_iommu_group_id(u8 bus, u8 devfn) return rt; } +#include + const struct iommu_ops amd_iommu_ops = { .init = amd_iommu_domain_init, .dom0_init = amd_iommu_dom0_init, @@ -480,7 +482,7 @@ const struct iommu_ops amd_iommu_ops = { .get_device_group_id = amd_iommu_group_id, .update_ire_from_apic = amd_iommu_ioapic_update_ire, .update_ire_from_msi = amd_iommu_msi_msg_update_ire, - .read_apic_from_ire = amd_iommu_read_ioapic_from_ire, + .read_apic_from_ire = __io_apic_read, .read_msi_from_ire = amd_iommu_read_msi_from_ire, .suspend = amd_iommu_suspend, .resume = amd_iommu_resume, diff --git a/xen/drivers/passthrough/vtd/intremap.c b/xen/drivers/passthrough/vtd/intremap.c index 046a216619..bb57b43dd8 100644 --- a/xen/drivers/passthrough/vtd/intremap.c +++ b/xen/drivers/passthrough/vtd/intremap.c @@ -34,6 +34,22 @@ #ifdef __ia64__ #define nr_ioapics iosapic_get_nr_iosapics() #define nr_ioapic_registers(i) iosapic_get_nr_pins(i) +#define __io_apic_read(apic, reg) \ + (*IO_APIC_BASE(apic) = reg, *(IO_APIC_BASE(apic)+4)) +#define __io_apic_write(apic, reg, val) \ + (*IO_APIC_BASE(apic) = reg, *(IO_APIC_BASE(apic)+4) = (val)) +#define __ioapic_read_entry(apic, pin, raw) ({ \ + struct IO_xAPIC_route_entry _e_; \ + ASSERT(raw); \ + ((u32 *)&_e_)[0] = __io_apic_read(apic, 0x10 + 2 * (pin)); \ + ((u32 *)&_e_)[1] = __io_apic_read(apic, 0x11 + 2 * (pin)); \ + _e_; \ +}) +#define __ioapic_write_entry(apic, pin, raw, ent) ({ \ + ASSERT(raw); \ + __io_apic_write(apic, 0x10 + 2 * (pin), ((u32 *)&_e_)[0]); \ + __io_apic_write(apic, 0x11 + 2 * (pin), ((u32 *)&_e_)[1]); \ +}) #else #include #include @@ -374,25 +390,12 @@ unsigned int io_apic_read_remap_rte( if ( !iommu || !ir_ctrl || ir_ctrl->iremap_maddr == 0 || (ir_ctrl->iremap_num == 0) || ( (index = apic_pin_2_ir_idx[apic][ioapic_pin]) < 0 ) ) - { - *IO_APIC_BASE(apic) = reg; - return *(IO_APIC_BASE(apic)+4); - } - - if ( rte_upper ) - reg--; + return __io_apic_read(apic, reg); - /* read lower and upper 32-bits of rte entry */ - *IO_APIC_BASE(apic) = reg; - *(((u32 *)&old_rte) + 0) = *(IO_APIC_BASE(apic)+4); - *IO_APIC_BASE(apic) = reg + 1; - *(((u32 *)&old_rte) + 1) = *(IO_APIC_BASE(apic)+4); + old_rte = __ioapic_read_entry(apic, ioapic_pin, TRUE); if ( remap_entry_to_ioapic_rte(iommu, index, &old_rte) ) - { - *IO_APIC_BASE(apic) = rte_upper ? (reg + 1) : reg; - return *(IO_APIC_BASE(apic)+4); - } + return __io_apic_read(apic, reg); if ( rte_upper ) return (*(((u32 *)&old_rte) + 1)); @@ -413,49 +416,31 @@ void io_apic_write_remap_rte( if ( !iommu || !ir_ctrl || ir_ctrl->iremap_maddr == 0 ) { - *IO_APIC_BASE(apic) = reg; - *(IO_APIC_BASE(apic)+4) = value; + __io_apic_write(apic, reg, value); return; } - if ( rte_upper ) - reg--; - - /* read both lower and upper 32-bits of rte entry */ - *IO_APIC_BASE(apic) = reg; - *(((u32 *)&old_rte) + 0) = *(IO_APIC_BASE(apic)+4); - *IO_APIC_BASE(apic) = reg + 1; - *(((u32 *)&old_rte) + 1) = *(IO_APIC_BASE(apic)+4); + old_rte = __ioapic_read_entry(apic, ioapic_pin, TRUE); remap_rte = (struct IO_APIC_route_remap_entry *) &old_rte; /* mask the interrupt while we change the intremap table */ saved_mask = remap_rte->mask; remap_rte->mask = 1; - *IO_APIC_BASE(apic) = reg; - *(IO_APIC_BASE(apic)+4) = *(((int *)&old_rte)+0); + __io_apic_write(apic, reg & ~1, *(u32 *)&old_rte); remap_rte->mask = saved_mask; if ( ioapic_rte_to_remap_entry(iommu, apic, ioapic_pin, &old_rte, rte_upper, value) ) { - *IO_APIC_BASE(apic) = rte_upper ? (reg + 1) : reg; - *(IO_APIC_BASE(apic)+4) = value; + __io_apic_write(apic, reg, value); /* Recover the original value of 'mask' bit */ if ( rte_upper ) - { - *IO_APIC_BASE(apic) = reg; - *(IO_APIC_BASE(apic)+4) = *(((u32 *)&old_rte)+0); - } - return; + __io_apic_write(apic, reg & ~1, *(u32 *)&old_rte); } - - /* write new entry to ioapic */ - *IO_APIC_BASE(apic) = reg + 1; - *(IO_APIC_BASE(apic)+4) = *(((u32 *)&old_rte)+1); - *IO_APIC_BASE(apic) = reg; - *(IO_APIC_BASE(apic)+4) = *(((u32 *)&old_rte)+0); + else + __ioapic_write_entry(apic, ioapic_pin, TRUE, old_rte); } #if defined(__i386__) || defined(__x86_64__) diff --git a/xen/drivers/passthrough/vtd/utils.c b/xen/drivers/passthrough/vtd/utils.c index cca5de02bf..9b504223aa 100644 --- a/xen/drivers/passthrough/vtd/utils.c +++ b/xen/drivers/passthrough/vtd/utils.c @@ -261,9 +261,8 @@ static void dump_iommu_info(unsigned char key) /* Dump the I/O xAPIC redirection table(s). */ if ( iommu_enabled ) { - int apic, reg; + int apic; union IO_APIC_reg_01 reg_01; - struct IO_APIC_route_entry rte = { 0 }; struct IO_APIC_route_remap_entry *remap; struct ir_ctrl *ir_ctrl; @@ -277,19 +276,14 @@ static void dump_iommu_info(unsigned char key) printk( "\nRedirection table of IOAPIC %x:\n", apic); - reg = 1; /* IO xAPIC Version Register. */ - *IO_APIC_BASE(apic) = reg; - reg_01.raw = *(IO_APIC_BASE(apic)+4); + /* IO xAPIC Version Register. */ + reg_01.raw = __io_apic_read(apic, 1); printk(" #entry IDX FMT MASK TRIG IRR POL STAT DELI VECTOR\n"); for ( i = 0; i <= reg_01.bits.entries; i++ ) { - reg = 0x10 + i*2; - *IO_APIC_BASE(apic) = reg; - *(((u32 *)&rte) + 0) = *(IO_APIC_BASE(apic)+4); - - *IO_APIC_BASE(apic) = reg + 1; - *(((u32 *)&rte) + 1) = *(IO_APIC_BASE(apic)+4); + struct IO_APIC_route_entry rte = + __ioapic_read_entry(apic, i, TRUE); remap = (struct IO_APIC_route_remap_entry *) &rte; if ( !remap->format ) diff --git a/xen/drivers/passthrough/vtd/vtd.h b/xen/drivers/passthrough/vtd/vtd.h index a1a21db293..499c3d3eb1 100644 --- a/xen/drivers/passthrough/vtd/vtd.h +++ b/xen/drivers/passthrough/vtd/vtd.h @@ -27,6 +27,9 @@ #define UNMAP_ME_PHANTOM_FUNC 0 /* Accomodate both IOAPIC and IOSAPIC. */ +#ifndef __ia64__ +#define IO_xAPIC_route_entry IO_APIC_route_entry +#else struct IO_xAPIC_route_entry { __u32 vector : 8, delivery_mode : 3, /* 000: FIXED @@ -53,15 +56,14 @@ struct IO_xAPIC_route_entry { logical_dest : 8; } logical; -#ifdef __ia64__ struct { __u32 __reserved_1 : 16, dest_id : 16; }; -#endif } dest; } __attribute__ ((packed)); +#endif struct IO_APIC_route_remap_entry { union { diff --git a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h index b14e387538..1444e9104c 100644 --- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h @@ -93,8 +93,6 @@ void amd_iommu_msi_msg_update_ire( struct msi_desc *msi_desc, struct msi_msg *msg); void amd_iommu_read_msi_from_ire( struct msi_desc *msi_desc, struct msi_msg *msg); -unsigned int amd_iommu_read_ioapic_from_ire( - unsigned int apic, unsigned int reg); extern int ioapic_bdf[MAX_IO_APICS]; extern void *shared_intremap_table; diff --git a/xen/include/asm-x86/io_apic.h b/xen/include/asm-x86/io_apic.h index 4bbbbe79d3..066a00cd07 100644 --- a/xen/include/asm-x86/io_apic.h +++ b/xen/include/asm-x86/io_apic.h @@ -200,6 +200,12 @@ extern void ioapic_resume(void); extern void dump_ioapic_irq_info(void); +extern struct IO_APIC_route_entry __ioapic_read_entry( + unsigned int apic, unsigned int pin, bool_t raw); +void __ioapic_write_entry( + unsigned int apic, unsigned int pin, bool_t raw, + struct IO_APIC_route_entry); + extern struct IO_APIC_route_entry **alloc_ioapic_entries(void); extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries); extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);